package ru.dc.object.commands;

import org.apache.commons.lang.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <pre>
 * User: Penkov Vladimir
 * Date: 08.10.2010
 * Time: 16:45:11
 * </pre>
 */
public class Lock extends Command {

    static Pattern p = Pattern.compile("\\$Lock (.*?) Pk=(.+)$");
    private String lock;
    private String pk;
    private boolean supportsExtended;
    public static final String EXTENDED_MARKER = "EXTENDEDPROTOCOL";

    @Override
    public String generateCommand() {
        return getActualCommandName()+" "+getLock()+" Pk="+getPk();
    }

    @Override
    public String getActualCommandName() {
        return "$Lock";
    }

    @Override
    public void parseCommand() {
        //TODO избавиться от регэкспа
        Matcher m = p.matcher(getCommand());
        if (m.find()) {
            setLock(m.group(1));
            setPk(m.group(2));
            setSupportsExtended(!StringUtils.isEmpty(getLock()) && getLock().startsWith(EXTENDED_MARKER));
        }

    }

    public String getLock() {
        return lock;
    }

    public void setLock(String lock) {
        this.lock = lock;
    }

    public String getPk() {
        return pk;
    }

    public void setPk(String pk) {
        this.pk = pk;
    }

    public boolean isSupportsExtended() {
        return supportsExtended;
    }

    public void setSupportsExtended(boolean supportsExtended) {
        this.supportsExtended = supportsExtended;
    }

    @Override
    public String toString() {
        return "Lock{" +
                "lock='" + lock + '\'' +
                ", pk='" + pk + '\'' +
                '}';
    }


    public static String convertLockToKey(String lockStr) {
        byte[] lock = lockStr.getBytes();
        final int len = lock.length;
        byte[] key = new byte[len];

        for (int i = 1; i < len; i++) {
            key[i] = (byte) (lock[i] ^ lock[i-1]);
        }
        key[0] = (byte) (lock[0] ^ lock[len-1] ^ lock[len-2] ^ 5);
        for (int i = 0; i < len; i++) {
            key[i] = (byte) (((key[i]<<4) & 240) | ((key[i]>>4) & 15));
        }

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < len; i++) {
            String append;
            switch (key[i]) {
                case 0 :
                    append = "/%DCN000%/";
                    break;
                case 5 :
                    append = "/%DCN005%/";
                    break;
                case 36 :
                    append = "/%DCN036%/";
                    break;
                case 96 :
                    append = "/%DCN096%/";
                    break;
                case 124 :
                    append = "/%DCN124%/";
                    break;
                case 126 :
                    append = "/%DCN126%/";
                    break;
                default:
                    Character ch = (char) key[i];
                    append = ch.toString();
            }

            sb.append(append);
        }
        return sb.toString();
    }


}
